<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
	<head>
		<!--
			JS/CC: A LALR(1) Compiler-Compiler written in JavaScript
			Copyright (C) 2007, 2008 by J.M.K S.F. Software Technologies, Jan Max Meyer
			http://www.jmksf.com ++ jscc<-AT->jmksf.com
			
			File:	jscc.html
			Author:	Jan Max Meyer
			Usage:	Web Environment Module
			
			You may use, modify and distribute this software under the terms and conditions
			of the Artistic License. Please see ARTISTIC for more information.
		-->
		<title>JS/CC Web Environment</title>
		
		<meta http-equiv="Content-Script-Type" content="text/javascript" />
		
		<link rel="stylesheet" href="jscc.css" type="text/css" />
		
		<script type="text/javascript" src="src/jscc_global.js"></script>
		<script type="text/javascript" src="src/jscc_debug.js"></script>
		<script type="text/javascript" src="src/jscc_first.js"></script>	
		<script type="text/javascript" src="src/jscc_PARSE_WEB.js"></script>
		<script type="text/javascript" src="src/jscc_printtab.js"></script>
		<script type="text/javascript" src="src/jscc_tabgen.js"></script>
		<script type="text/javascript" src="src/jscc_bitset.js"></script>
		<script type="text/javascript" src="src/jscc_lexdfa.js"></script>
		<script type="text/javascript" src="src/jscc_lexdbg.js"></script>
		<script type="text/javascript" src="src/jscc_REGEX_WEB.js"></script>
		<script type="text/javascript" src="src/jscc_util.js"></script>
		<script type="text/javascript" src="src/jscc_integrity.js"></script>

		<script type="text/javascript">
		var phypeDoc = null;
		var html_output = new String();
		var error_output = new String();
		var	dfa_table;
		
		function _error( msg )
		{
			if( show_errors )
				error_output += "Error: " + msg + "\n";

			errors++;
		}
		
		function _warning( msg )
		{
			if( show_warnings )
				error_output += "Warning: " + msg + "\n";

			warnings++;
		}
		
		function _print( txt )
		{
			html_output += txt;
		}
		
		function check_editor_content()
		{
			if( document.source.code.value != "" )
				if( confirm( "Delete current editor content?" ) )
				{
					document.source.code.value = "";
					document.source.code.focus();
					document.source.run.disabled = true;
					return true;
				}
				else
					return false;

			return true;
		}
		
		function load_grammar()
		{
			if( check_editor_content() )
			{
				document.source.code.value = grammars[ document.source.stored.value ];
				document.source.code.focus();
				
				document.source.run.disabled = true;
			}
		}
		
		function enlarge_content( container )
		{
			var closebutton = "<div style=\"width:100%; text-align: center;\"><input type=\"button\" onclick=\"hide_enlarged_content();\" width=\"100%\" value=\"Close\" /></div>";
			var pop_up = document.getElementById( "popupcontent" );
			pop_up.style.top = "100px";
			pop_up.style.left = "200px";
			pop_up.style.width = "800px";
			pop_up.style.height = "600px";
			
			pop_up.innerHTML = closebutton + "<hr />" +
				document.getElementById( container ).innerHTML +
					"<hr />" +  closebutton;

			pop_up.style.visibility = "visible";
		}
		
		function hide_enlarged_content()
		{
			var pop_up = document.getElementById("popupcontent");
			pop_up.style.visibility = "hidden";	
		}
		
		function run_parser()
		{
			var driver = "##HEADER##\nvar _dbg_withtrace = false; var _dbg_string = new String(); function __dbg_print( text )\n{ _dbg_string += text + \"\\n\";}\nfunction __lex( info )\n{ var state = 0; var match = -1; var match_pos = 0; var start = 0; var pos = info.offset + 1; do\n{ pos--; state = 0; match = -2; start = pos; if( info.src.length <= start )\nreturn ##EOF##; do\n{ ##DFA##\npos++;}\nwhile( state > -1 );}\nwhile( ##WHITESPACE## > -1 && match == ##WHITESPACE## ); if( match > -1 )\n{ info.att = info.src.substr( start, match_pos - start ); info.offset = match_pos; ##TERMINAL_ACTIONS##\n}\nelse\n{ info.att = new String(); match = -1;}\nreturn match;}\nfunction __parse( src, err_off, err_la )\n{ var sstack = new Array(); var vstack = new Array(); var err_cnt = 0; var act; var go; var la; var rval; var parseinfo = new Function( \"\", \"var offset; var src; var att;\" ); var info = new parseinfo(); ##TABLES##\n##LABELS##\ninfo.offset = 0; info.src = src; info.att = new String(); if( !err_off )\nerr_off = new Array(); if( !err_la )\nerr_la = new Array(); sstack.push( 0 ); vstack.push( 0 ); la = __lex( info ); while( true )\n{ act = ##ERROR##; for( var i = 0; i < act_tab[sstack[sstack.length-1]].length; i+=2 )\n{ if( act_tab[sstack[sstack.length-1]][i] == la )\n{ act = act_tab[sstack[sstack.length-1]][i+1]; break;}\n}\nif( _dbg_withtrace && sstack.length > 0 )\n{ __dbg_print( \"\\nState \" + sstack[sstack.length-1] + \"\\n\" + \"\\tLookahead: \" + labels[la] + \" (\\\"\" + info.att + \"\\\")\\n\" + \"\\tAction: \" + act + \"\\n\" + \"\\tSource: \\\"\" + info.src.substr( info.offset, 30 ) + ( ( info.offset + 30 < info.src.length ) ?\n\"...\" : \"\" ) + \"\\\"\\n\" + \"\\tStack: \" + sstack.join() + \"\\n\" + \"\\tValue stack: \" + vstack.join() + \"\\n\" );}\nif( act == ##ERROR## )\n{ if( _dbg_withtrace )\n__dbg_print( \"Error detected: There is no reduce or shift on the symbol \" + labels[la] ); err_cnt++; err_off.push( info.offset - info.att.length ); err_la.push( new Array() ); for( var i = 0; i < act_tab[sstack[sstack.length-1]].length; i+=2 )\nerr_la[err_la.length-1].push( labels[act_tab[sstack[sstack.length-1]][i]] ); var rsstack = new Array(); var rvstack = new Array(); for( var i = 0; i < sstack.length; i++ )\n{ rsstack[i] = sstack[i]; rvstack[i] = vstack[i];}\nwhile( act == ##ERROR## && la != ##EOF## )\n{ if( _dbg_withtrace )\n__dbg_print( \"\\tError recovery\\n\" + \"Current lookahead: \" + labels[la] + \" (\" + info.att + \")\\n\" + \"Action: \" + act + \"\\n\\n\" ); if( la == -1 )\ninfo.offset++; while( act == ##ERROR## && sstack.length > 0 )\n{ sstack.pop(); vstack.pop(); if( sstack.length == 0 )\nbreak; act = ##ERROR##; for( var i = 0; i < act_tab[sstack[sstack.length-1]].length; i+=2 )\n{ if( act_tab[sstack[sstack.length-1]][i] == la )\n{ act = act_tab[sstack[sstack.length-1]][i+1]; break;}\n}\n}\nif( act != ##ERROR## )\nbreak; for( var i = 0; i < rsstack.length; i++ )\n{ sstack.push( rsstack[i] ); vstack.push( rvstack[i] );}\nla = __lex( info );}\nif( act == ##ERROR## )\n{ if( _dbg_withtrace )\n__dbg_print( \"\\tError recovery failed, terminating parse process...\" ); break;}\nif( _dbg_withtrace )\n__dbg_print( \"\\tError recovery succeeded, continuing\" );}\nif( act > 0 )\n{ if( _dbg_withtrace )\n__dbg_print( \"Shifting symbol: \" + labels[la] + \" (\" + info.att + \")\" ); sstack.push( act ); vstack.push( info.att ); la = __lex( info ); if( _dbg_withtrace )\n__dbg_print( \"\\tNew lookahead symbol: \" + labels[la] + \" (\" + info.att + \")\" );}\nelse\n{ act *= -1; if( _dbg_withtrace )\n__dbg_print( \"Reducing by producution: \" + act ); rval = void(0); if( _dbg_withtrace )\n__dbg_print( \"\\tPerforming semantic action...\" ); ##ACTIONS##\nif( _dbg_withtrace )\n__dbg_print( \"\\tPopping \" + pop_tab[act][1] + \" off the stack...\" ); for( var i = 0; i < pop_tab[act][1]; i++ )\n{ sstack.pop(); vstack.pop();}\ngo = -1; for( var i = 0; i < goto_tab[sstack[sstack.length-1]].length; i+=2 )\n{ if( goto_tab[sstack[sstack.length-1]][i] == pop_tab[act][0] )\n{ go = goto_tab[sstack[sstack.length-1]][i+1]; break;}\n}\nif( act == 0 )\nbreak; if( _dbg_withtrace )\n__dbg_print( \"\\tPushing non-terminal \" + labels[ pop_tab[act][0] ] ); sstack.push( go ); vstack.push( rval );}\nif( _dbg_withtrace )\n{ alert( _dbg_string ); _dbg_string = new String();}\n}\nif( _dbg_withtrace )\n{ __dbg_print( \"\\nParse complete.\" ); alert( _dbg_string );}\nreturn err_cnt;}\n##FOOTER##";
			var webdriver = "##HEADER##\n\n/*\n\tJS/CC: A LALR(1) Compiler-Compiler written in JavaScript\n\tCopyright (C) 2007, 2008 by J.M.K S.F. Software Technologies, Jan Max Meyer\n\thttp://www.jmksf.com ++ jscc<-AT->jmksf.com\n\t\n\tFile:\tjscc.html\n\tAuthor:\tJan Max Meyer\n\tUsage:\tModified parser template for the Web Environment Module\n\t\t\tBased on \"driver_web.js_\" parser template, but NOT in the public domain!\n\t\n\tYou may use, modify and distribute this software under the terms and conditions\n\tof the Artistic License. Please see ARTISTIC for more information.\n\n\tDriver for the JS/CC Web Environment with integrated HTML parse tree generator!\n\t\n\tFeatures:\n\t- Parser trace messages\n\t- Integrated panic-mode error recovery\n\t- Parse tree construction for the JS/CC web environment\n*/\n\nvar _dbg_withtrace\t\t= false;\nvar _dbg_string\t\t\t= new String();\n\nfunction __dbg_print( text )\n{\n\t_dbg_string += text + \"\\n\";\n}\n\nfunction __lex( info )\n{\n\tvar state\t\t= 0;\n\tvar match\t\t= -1;\n\tvar match_pos\t= 0;\n\tvar start\t\t= 0;\n\tvar pos\t\t\t= info.offset + 1;\n\n\tdo\n\t{\n\t\tpos--;\n\t\tstate = 0;\n\t\tmatch = -2;\n\t\tstart = pos;\n\n\t\tif( info.src.length <= start )\n\t\t\treturn ##EOF##;\n\n\t\tdo\n\t\t{\n\n##DFA##\n\t\t\tpos++;\n\n\t\t}\n\t\twhile( state > -1 );\n\n\t}\n\twhile( ##WHITESPACE## > -1 && match == ##WHITESPACE## );\n\n\tif( match > -1 )\n\t{\n\t\tinfo.att = info.src.substr( start, match_pos - start );\n\t\tinfo.offset = match_pos;\n\t\t\n##TERMINAL_ACTIONS##\n\t}\n\telse\n\t{\n\t\tinfo.att = new String();\n\t\tmatch = -1;\n\t}\n\n\treturn match;\n}\n\n\nfunction __parse( src, err_off, err_la )\n{\n\tvar\t\tsstack\t\t\t= new Array();\n\tvar\t\tvstack\t\t\t= new Array();\n\tvar \terr_cnt\t\t\t= 0;\n\tvar\t\tact;\n\tvar\t\tgo;\n\tvar\t\tla;\n\tvar\t\trval;\n\tvar \tparseinfo\t\t= new Function( \"\", \"var offset; var src; var att;\" );\n\tvar\t\tinfo\t\t\t= new parseinfo();\n\t\n\t//Visual parse tree generation\n\tvar \ttreenode\t\t= new Function( \"\", \"var sym; var att; var child;\" );\n\tvar\t\ttreenodes\t\t= new Array();\n\tvar\t\ttree\t\t\t= new Array();\n\tvar\t\ttmptree\t\t\t= null;\n\t\n##TABLES##\n\n##LABELS##\n\t\n\tinfo.offset = 0;\n\tinfo.src = src;\n\tinfo.att = new String();\n\t\n\tif( !err_off )\n\t\terr_off\t= new Array();\n\tif( !err_la )\n\terr_la = new Array();\n\t\n\tsstack.push( 0 );\n\tvstack.push( 0 );\n\t\n\tla = __lex( info );\n\n\twhile( true )\n\t{\n\t\tact = ##ERROR##;\n\t\tfor( var i = 0; i < act_tab[sstack[sstack.length-1]].length; i+=2 )\n\t\t{\n\t\t\tif( act_tab[sstack[sstack.length-1]][i] == la )\n\t\t\t{\n\t\t\t\tact = act_tab[sstack[sstack.length-1]][i+1];\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif( _dbg_withtrace && sstack.length > 0 )\n\t\t{\n\t\t\t__dbg_print( \"\\nState \" + sstack[sstack.length-1] + \"\\n\" +\n\t\t\t\t\t\t\t\"\\tLookahead: \" + labels[la] + \" (\\\"\" + info.att + \"\\\")\\n\" +\n\t\t\t\t\t\t\t\"\\tAction: \" + act + \"\\n\" + \n\t\t\t\t\t\t\t\"\\tSource: \\\"\" + info.src.substr( info.offset, 30 ) + ( ( info.offset + 30 < info.src.length ) ?\n\t\t\t\t\t\t\t\t\t\"...\" : \"\" ) + \"\\\"\\n\" +\n\t\t\t\t\t\t\t\"\\tStack: \" + sstack.join() + \"\\n\" +\n\t\t\t\t\t\t\t\"\\tValue stack: \" + vstack.join() + \"\\n\" );\n\t\t}\n\t\t\n\t\t\t\n\t\t//Panic-mode: Try recovery when parse-error occurs!\n\t\tif( act == ##ERROR## )\n\t\t{\n\t\t\tif( _dbg_withtrace )\n\t\t\t\t__dbg_print( \"Error detected: There is no reduce or shift on the symbol \" + labels[la] );\n\t\t\t\n\t\t\terr_cnt++;\n\t\t\terr_off.push( info.offset - info.att.length );\t\t\t\n\t\t\terr_la.push( new Array() );\n\t\t\tfor( var i = 0; i < act_tab[sstack[sstack.length-1]].length; i+=2 )\n\t\t\t\terr_la[err_la.length-1].push( labels[act_tab[sstack[sstack.length-1]][i]] );\n\t\t\t\n\t\t\t//Remember the original stack!\n\t\t\tvar rsstack = new Array();\n\t\t\tvar rvstack = new Array();\n\t\t\tfor( var i = 0; i < sstack.length; i++ )\n\t\t\t{\n\t\t\t\trsstack[i] = sstack[i];\n\t\t\t\trvstack[i] = vstack[i];\n\t\t\t}\n\t\t\t\n\t\t\twhile( act == ##ERROR## && la != ##EOF## )\n\t\t\t{\n\t\t\t\tif( _dbg_withtrace )\n\t\t\t\t\t__dbg_print( \"\\tError recovery\\n\" +\n\t\t\t\t\t\t\t\t\t\"Current lookahead: \" + labels[la] + \" (\" + info.att + \")\\n\" +\n\t\t\t\t\t\t\t\t\t\"Action: \" + act + \"\\n\\n\" );\n\t\t\t\tif( la == -1 )\n\t\t\t\t\tinfo.offset++;\n\t\t\t\t\t\n\t\t\t\twhile( act == ##ERROR## && sstack.length > 0 )\n\t\t\t\t{\n\t\t\t\t\tsstack.pop();\n\t\t\t\t\tvstack.pop();\n\t\t\t\t\t\n\t\t\t\t\tif( sstack.length == 0 )\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\n\t\t\t\t\tact = ##ERROR##;\n\t\t\t\t\tfor( var i = 0; i < act_tab[sstack[sstack.length-1]].length; i+=2 )\n\t\t\t\t\t{\n\t\t\t\t\t\tif( act_tab[sstack[sstack.length-1]][i] == la )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tact = act_tab[sstack[sstack.length-1]][i+1];\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tif( act != ##ERROR## )\n\t\t\t\t\tbreak;\n\t\t\t\t\n\t\t\t\tfor( var i = 0; i < rsstack.length; i++ )\n\t\t\t\t{\n\t\t\t\t\tsstack.push( rsstack[i] );\n\t\t\t\t\tvstack.push( rvstack[i] );\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tla = __lex( info );\n\t\t\t}\n\t\t\t\n\t\t\tif( act == ##ERROR## )\n\t\t\t{\n\t\t\t\tif( _dbg_withtrace )\n\t\t\t\t\t__dbg_print( \"\\tError recovery failed, terminating parse process...\" );\n\t\t\t\tbreak;\n\t\t\t}\n\n\n\t\t\tif( _dbg_withtrace )\n\t\t\t\t__dbg_print( \"\\tError recovery succeeded, continuing\" );\n\t\t}\n\t\t\n\t\t/*\n\t\tif( act == ##ERROR## )\n\t\t\tbreak;\n\t\t*/\n\t\t\n\t\t\n\t\t//Shift\n\t\tif( act > 0 )\n\t\t{\n\t\t\t//Parse tree\n\t\t\tvar node = new treenode();\n\t\t\tnode.sym = labels[ la ];\n\t\t\tnode.att = info.att;\n\t\t\tnode.child = new Array();\n\t\t\ttree.push( treenodes.length );\n\t\t\ttreenodes.push( node );\n\t\t\t\n\t\t\tif( _dbg_withtrace )\n\t\t\t\t__dbg_print( \"Shifting symbol: \" + labels[la] + \" (\" + info.att + \")\" );\n\t\t\n\t\t\tsstack.push( act );\n\t\t\tvstack.push( info.att );\n\t\t\t\n\t\t\tla = __lex( info );\n\t\t\t\n\t\t\tif( _dbg_withtrace )\n\t\t\t\t__dbg_print( \"\\tNew lookahead symbol: \" + labels[la] + \" (\" + info.att + \")\" );\n\t\t}\n\t\t//Reduce\n\t\telse\n\t\t{\t\t\n\t\t\tact *= -1;\n\t\t\t\n\t\t\tif( _dbg_withtrace )\n\t\t\t\t__dbg_print( \"Reducing by producution: \" + act );\n\t\t\t\n\t\t\trval = void(0);\n\t\t\t\n\t\t\tif( _dbg_withtrace )\n\t\t\t\t__dbg_print( \"\\tPerforming semantic action...\" );\n\t\t\t\n##ACTIONS##\n\n\t\t\ttmptree = new Array();\n\n\t\t\tif( _dbg_withtrace )\n\t\t\t\t__dbg_print( \"\\tPopping \" + pop_tab[act][1] + \" off the stack...\" );\n\t\t\t\t\n\t\t\tfor( var i = 0; i < pop_tab[act][1]; i++ )\n\t\t\t{\t\t\t\n\t\t\t\ttmptree.push( tree.pop() );\n\n\t\t\t\tsstack.pop();\n\t\t\t\tvstack.pop();\n\t\t\t}\n\t\t\t\t\t\t\t\t\t\n\t\t\tgo = -1;\n\t\t\tfor( var i = 0; i < goto_tab[sstack[sstack.length-1]].length; i+=2 )\n\t\t\t{\n\t\t\t\tif( goto_tab[sstack[sstack.length-1]][i] == pop_tab[act][0] )\n\t\t\t\t{\n\t\t\t\t\tgo = goto_tab[sstack[sstack.length-1]][i+1];\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\t//Parse tree\n\t\t\tvar node = new treenode();\n\t\t\tnode.sym = labels[ pop_tab[act][0] ];\n\t\t\tnode.att = rval;\n\t\t\tnode.child = tmptree.reverse();\n\t\t\ttree.push( treenodes.length );\n\t\t\ttreenodes.push( node );\n\t\t\t\n\t\t\tif( act == 0 )\n\t\t\t\tbreak;\n\t\t\t\t\n\t\t\tif( _dbg_withtrace )\n\t\t\t\t__dbg_print( \"\\tPushing non-terminal \" + labels[ pop_tab[act][0] ] );\n\t\t\t\t\n\t\t\tsstack.push( go );\n\t\t\tvstack.push( rval );\t\t\t\n\t\t}\n\t\t\n\t\tif( _dbg_withtrace )\n\t\t{\t\t\n\t\t\talert( _dbg_string );\n\t\t\t_dbg_string = new String();\n\t\t}\n\t}\n\n\tif( _dbg_withtrace )\n\t{\n\t\t__dbg_print( \"\\nParse complete.\" );\n\t\talert( _dbg_string );\n\t}\n\t\n\tif( err_cnt == 0 )\n\t{\n\t\tdocument.getElementById( \"parsetree\" ).innerHTML =__dbg_parsetree( 0, 0,\n\t\t\t__dbg_get_tree_depth( treenodes, tree, 0 ), treenodes, tree );\n\t}\n\t\n\treturn err_cnt;\n}\n\nfunction __dbg_image( name )\n{\n\treturn \"<img src=\\\"img/\" + name + \".png\\\" style=\\\"border: 0px; margin: 0px; padding: 0px;\\\" />\";\n}\n\nfunction __dbg_get_tree_depth( nodes, tree, max )\n{\n\tvar\t\ttmp\t\t= 0;\n\t\n\tfor( var i = 0; i < tree.length; i++ )\n\t{\n\t\tif( nodes[ tree[i] ].child.length > 0 )\n\t\t\tif( max < ( tmp = __dbg_get_tree_depth( nodes, nodes[ tree[i] ].child, max+1 ) ) )\n\t\t\t\tmax = tmp;\n\t}\n\t\n\treturn max;\n}\n\nfunction __dbg_parsetree( prev, cnt, depth, nodes, tree )\n{\n\tvar str = new String();\n\t\n\tif( cnt == 0 )\n\t\tstr += \"<table border=\\\"0\\\" cellpadding=\\\"0\\\" cellspacing=\\\"0\\\" class=\\\"parsetree\\\">\";\n\t\n\tif( !prev )\n\t\tprev = new Array();\n\t\t\n\tif( cnt > 0 )\n\t\tprev[cnt-1] = true;\n\t\t\t\n\tfor( var i = 0; i < tree.length; i++ )\n\t{\n\t\tstr += \"<tr>\";\n\n\t\tfor( var j = 0; j < cnt; j++ )\n\t\t{\n\t\t\tstr += \"<td>\";\n\n\t\t\tif( prev[j] )\n\t\t\t{\n\t\t\t\tif( j == cnt - 1 && i == tree.length - 1 )\n\t\t\t\t\tstr += __dbg_image( \"ll\" );\n\t\t\t\telse if( j == cnt - 1 )\n\t\t\t\t\tstr += __dbg_image( \"la\" );\n\t\t\t\telse\n\t\t\t\t\tstr += __dbg_image( \"l\" );\n\t\t\t}\n\t\t\telse\n\t\t\t\tstr += __dbg_image( \"e\" );\n\t\t\t\t\n\t\t\tstr += \"</td>\";\n\t\t}\n\t\t\n\t\tif( cnt > 0 && i == tree.length - 1 )\n\t\t\tprev[cnt-1] = false;\n\n\t\tstr += \"<td>\";\n\t\tif( nodes[ tree[i] ].child.length > 0 )\n\t\t\tif( cnt == 0 )\n\t\t\t\tstr += __dbg_image( \"rn\" );\n\t\t\telse\n\t\t\t\tstr += __dbg_image( \"n\" );\t\n\t\telse\n\t\t\tstr += __dbg_image( \"t\" );\n\t\tstr += \"</td>\";\n\t\t\n\t\tstr += \"<td class=\\\"node_name\\\" colspan=\\\"\" + ( depth - cnt + 1 ) + \"\\\">\" + nodes[ tree[i] ].sym ;\n\t\tif( nodes[ tree[i] ].att && nodes[ tree[i] ].att != \"\" )\n\t\t\tstr += \":<span>\" + nodes[ tree[i] ].att + \"</span>\" ;\n\t\t\t\n\t\tstr += \"</td>\";\n\n\t\tif( nodes[ tree[i] ].child.length > 0 )\n\t\t\tstr += __dbg_parsetree( prev, cnt+1, depth, nodes, nodes[ tree[i] ].child );\n\t}\n\t\n\tif( cnt == 0 )\n\t\tstr += \"</table>\";\n\t\n\treturn str;\n}\n\n##FOOTER##\n";
				
			if( !code_foot )
				code_foot = "var error_offsets = new Array(); var error_lookaheads = new Array(); var error_count = 0; var str = prompt( \"Please enter a string to be parsed:\", \"\" ); if( ( error_count = __parse( str, error_offsets, error_lookaheads ) ) > 0 ) { var errstr = new String(); for( var i = 0; i < error_count; i++ ) errstr += \"Parse error in line \" + ( str.substr( 0, error_offsets[i] ).match( /\\n/g ) ? str.substr( 0, error_offsets[i] ).match( /\\n/g ).length : 1 ) + \" near \\\"\" + str.substr( error_offsets[i] ) + \"\\\", expecting \\\"\" + error_lookaheads[i].join() + \"\\\"\\n\" ; alert( errstr );}";

			//driver is for output
			driver = driver.replace( /##HEADER##/gi, code_head );
			driver = driver.replace( /##TABLES##/gi, print_parse_tables( MODE_GEN_JS ) );
			driver = driver.replace( /##DFA##/gi, print_dfa_table( dfa_table ) );
			driver = driver.replace( /##TERMINAL_ACTIONS##/gi, print_term_actions() );
			driver = driver.replace( /##LABELS##/gi, print_symbol_labels() );
			driver = driver.replace( /##ACTIONS##/gi, print_actions() );
			driver = driver.replace( /##FOOTER##/gi, code_foot );
			driver = driver.replace( /##ERROR##/gi, get_error_symbol_id() );
			driver = driver.replace( /##EOF##/gi, get_eof_symbol_id() );
			driver = driver.replace( /##WHITESPACE##/gi, get_whitespace_symbol_id() );
			
			//webdriver is for execution and parse tree generator
			webdriver = webdriver.replace( /##HEADER##/gi, code_head );
			webdriver = webdriver.replace( /##TABLES##/gi, print_parse_tables( MODE_GEN_JS ) );
			webdriver = webdriver.replace( /##DFA##/gi, print_dfa_table( dfa_table ) );
			webdriver = webdriver.replace( /##TERMINAL_ACTIONS##/gi, print_term_actions() );
			webdriver = webdriver.replace( /##LABELS##/gi, print_symbol_labels() );
			webdriver = webdriver.replace( /##ACTIONS##/gi, print_actions() );
			webdriver = webdriver.replace( /##FOOTER##/gi, code_foot );
			webdriver = webdriver.replace( /##ERROR##/gi, get_error_symbol_id() );
			webdriver = webdriver.replace( /##EOF##/gi, get_eof_symbol_id() );
			webdriver = webdriver.replace( /##WHITESPACE##/gi, get_whitespace_symbol_id() );			
			//driver = webdriver;
			
			//output the code
			document.getElementById( "js_code" ).innerHTML = driver.replace( /\n/g, "<br />" ).replace( /\t/g, "&nbsp;&nbsp;&nbsp;&nbsp;" );
			
			//Print the code
			function codePrinter(message) {
				if (!codePrinter.window_ || codePrinter.window_.closed) {
					var codePrinterWin = window.open("", "codePrinter", "width=600,height=400," +
										"scrollbars=yes,resizable=yes,status=no," +
										"location=no,menubar=no,toolbar=no");
					if (!codePrinterWin) return;
					var doc = codePrinterWin.document;
					doc.close();
					codePrinter.window_ = codePrinterWin;
				}
				doc.write(message);
			}
			codePrinter(driver.replace( /</g, "&lt;" ).replace( />/g, "&gt;" ).replace( /\n/g, "<br />" ).replace( /\t/g, "&nbsp;&nbsp;&nbsp;&nbsp;" ));

			//run the webdriver
			eval( webdriver );
		}
		
		function build()
		{
			var pure_code, out_code, i;
			
			html_output = new String();
			error_output = new String();
			reset_all( EXEC_WEB );
			
			show_warnings = document.source.with_warnings.checked;

			var src = new String( document.source.code.value );
			parse_grammar( src );
			
			if( errors == 0 )
			{
				undefined();
				unreachable();
				
				if( errors == 0 )
				{
					first();
					print_symbols();
					print_grammar( MODE_GEN_HTML );
					
					html_output += "<hr />";
					
					dfa_table = create_subset( nfa_states );
					dfa_table = minimize_dfa( dfa_table );

					lalr1_parse_table( true );
					
					errors = 0;
					if( errors == 0 )
						document.getElementById( "output" ).innerHTML = html_output + "<hr />" + print_parse_tables( MODE_GEN_HTML );
				}
			}

			if( errors > 0 || warnings > 0 && error_output != "" )
				alert( error_output );
			
			if( errors == 0 )
				document.source.run.disabled = false;
		}

		var grammars = new Array();
		grammars.push( "/~\n    This is a four-function calculator, where precedences\n    are defined via associativity definitions of tokens.\n\n    IMPORTANT: The Warnings coming up when invoking JS/CC\n               are coming from the grammar, and are resolved\n               in order to the precedences and associativity\n               information passed to each token.\n~/\n\n\n/~ --- Token definitions --- ~/\n\n/~ Characters to be ignored ~/\n!   \' |\\t\' ;\n\n/~ Non-associative tokens ~/\n    \'\\(\'\n    \'\\)\'\n    \'[0-9]+\'                        INT   [* %match = parseInt( %match ); *]\n    \'[0-9]+\\.[0-9]*|[0-9]*\\.[0-9]+\' FLOAT [* %match = parseFloat( %match ); *]\n    ;\n\n/~ Left-associative tokens, lowest precedence ~/\n<  \'\\+\'\n   \'\\-\';\n        \n/~ Left-associative tokens, highest precedence ~/\n<  \'\\*\'\n   \'/\';\n\n##\n\n/~ --- Grammar specification --- ~/\n\np:      e              [* alert( %1 ); *]\n        ;\n\ne:      e \'+\' e        [* %% = %1 + %3; *]\n        | e \'-\' e      [* %% = %1 - %3; *]\n        | e \'*\' e      [* %% = %1 * %3; *]\n        | e \'/\' e      [* %% = %1 / %3; *]\n        | \'-\' e &\'*\'   [* %% = %2 * -1; *]\n        | \'(\' e \')\'    [* %% = %2; *]\n        | INT\n        | FLOAT\n        ;" );
		
		grammars.push( "/~\n\tXPL - eXample Programming Language v0.3\n\tWritten 2007 by J.M.K S.F. Software Technologies, Jan Max Meyer\n\t\n\tThe complete source of this program is in the Public Domain.\n\t\n\tThis example demonstrates the implementation of XPL, a complete,\n\tinterpretered scripting language, written in JS/CC.\n\t\n\tXPL provides simple input/output operations and can only handle\n\tnumeric values.\n\t\n\tWatch out for the *.xpl-files within the example directory, which\n\tcontain example scripts to be executed using XPL, for example a\n\tcountdown or a calculator.\n~/\n\t\n\t\n[*\n\n//Structs\nfunction NODE()\n{\n\tvar type;\n\tvar value;\n\tvar children;\n}\n\n//Defines\nvar NODE_OP\t= 0;\nvar NODE_VAR\t= 1;\nvar NODE_CONST\t= 2;\n\nvar OP_NONE\t= -1;\nvar OP_ASSIGN\t= 0;\nvar OP_IF\t= 1;\nvar OP_IF_ELSE\t= 2;\nvar OP_WHILE_DO\t= 3;\nvar OP_DO_WHILE\t= 4;\nvar OP_WRITE\t= 5;\nvar OP_READ\t= 6;\nvar OP_SAY\t= 7;\n\nvar OP_EQU\t= 10;\nvar OP_NEQ\t= 11;\nvar OP_GRT\t= 12;\nvar OP_LOT\t= 13;\nvar OP_GRE\t= 14;\nvar OP_LOE\t= 15;\nvar OP_ADD\t= 16;\nvar OP_SUB\t= 17;\nvar OP_DIV\t= 18;\nvar OP_MUL\t= 19;\nvar OP_NEG\t= 20;\n\n//Management functions\nfunction createNode( type, value, childs )\n{\n\tvar n = new NODE();\n\tn.type = type;\n\tn.value = value;\t\n\tn.children = new Array();\n\t\n\tfor( var i = 2; i < arguments.length; i++ )\n\t\tn.children.push( arguments[i] );\n\t\t\n\treturn n;\n}\n\nvar v_names = new Array();\nvar v_values = new Array();\n\n//Interpreting function\nfunction letvar( vname, value )\n{\n\tvar i;\n\tfor( i = 0; i < v_names.length; i++ )\n\t\tif( v_names[i].toString() == vname.toString() )\n\t\t\tbreak;\n\t\t\n\tif( i == v_names.length )\n\t{\n\t\tv_names.push( vname );\n\t\tv_values.push( 0 );\n\t}\n\t\n\tv_values[i] = value;\n}\n\nfunction getvar( vname )\n{\n\tvar i;\n\tfor( i = 0; i < v_names.length; i++ )\n\t\tif( v_names[i].toString() == vname.toString() )\n\t\t\treturn v_values[i];\n\t\t\t\n\treturn 0;\n}\n\nfunction execute( node )\n{\n\tvar ret = 0;\n\t\n\tif( !node )\n\t\treturn 0;\n\t\t\n\tswitch( node.type )\n\t{\n\t\tcase NODE_OP:\n\t\t\tswitch( node.value )\n\t\t\t{\n\t\t\t\tcase OP_NONE:\n\t\t\t\t\tif( node.children[0] )\n\t\t\t\t\t\texecute( node.children[0] );\t\t\t\t\t\n\t\t\t\t\tif( node.children[1] )\n\t\t\t\t\t\tret = execute( node.children[1] );\n\t\t\t\t\tbreak;\n\t\t\t\tcase OP_ASSIGN:\n\t\t\t\t\tletvar( node.children[0], execute( node.children[1] ) );\n\t\t\t\t\tbreak;\n\t\t\t\tcase OP_IF:\n\t\t\t\t\tif( execute( node.children[0] ) )\n\t\t\t\t\t\texecute( node.children[1] );\n\t\t\t\t\tbreak;\n\t\t\t\tcase OP_IF_ELSE:\n\t\t\t\t\tif( execute( node.children[0] ) )\n\t\t\t\t\t\texecute( node.children[1] );\n\t\t\t\t\telse\n\t\t\t\t\t\texecute( node.children[2] );\n\t\t\t\t\tbreak;\n\t\t\t\tcase OP_WHILE_DO:\n\t\t\t\t\twhile( execute( node.children[0] ) )\n\t\t\t\t\t\texecute( node.children[1] );\n\t\t\t\t\tbreak;\n\t\t\t\tcase OP_DO_WHILE:\n\t\t\t\t\tdo\n\t\t\t\t\t\texecute( node.children[0] )\n\t\t\t\t\twhile( execute( node.children[1] ) );\n\t\t\t\t\tbreak;\n\t\t\t\tcase OP_WRITE:\n\t\t\t\t\talert( execute( node.children[0] ) );\n\t\t\t\t\tbreak;\n\t\t\t\tcase OP_READ:\n\t\t\t\t\tletvar( node.children[0].toString(), prompt( \"Please enter a value:\", \"0\"  ) );\n\t\t\t\t\tbreak;\n\t\t\t\tcase OP_SAY:\n\t\t\t\t\talert( node.children[0] );\n\t\t\t\t\tbreak;\n\t\t\t\tcase OP_EQU:\n\t\t\t\t\tret = execute( node.children[0] ) == execute( node.children[1] );\n\t\t\t\t\tbreak;\n\t\t\t\tcase OP_NEQ:\n\t\t\t\t\tret = execute( node.children[0] ) != execute( node.children[1] );\n\t\t\t\t\tbreak;\n\t\t\t\tcase OP_GRT:\n\t\t\t\t\tret = execute( node.children[0] ) > execute( node.children[1] );\n\t\t\t\t\tbreak;\n\t\t\t\tcase OP_LOT:\n\t\t\t\t\tret = execute( node.children[0] ) < execute( node.children[1] );\n\t\t\t\t\tbreak;\n\t\t\t\tcase OP_GRE:\n\t\t\t\t\tret = execute( node.children[0] ) >= execute( node.children[1] );\n\t\t\t\t\tbreak;\n\t\t\t\tcase OP_LOE:\n\t\t\t\t\tret = execute( node.children[0] ) <= execute( node.children[1] );\n\t\t\t\t\tbreak;\n\t\t\t\tcase OP_ADD:\n\t\t\t\t\tret = execute( node.children[0] ) + execute( node.children[1] );\n\t\t\t\t\tbreak;\n\t\t\t\tcase OP_SUB:\n\t\t\t\t\tret = execute( node.children[0] ) - execute( node.children[1] );\n\t\t\t\t\tbreak;\n\t\t\t\tcase OP_DIV:\n\t\t\t\t\tret = execute( node.children[0] ) / execute( node.children[1] );\n\t\t\t\t\tbreak;\n\t\t\t\tcase OP_MUL:\n\t\t\t\t\tret = execute( node.children[0] ) * execute( node.children[1] );\n\t\t\t\t\tbreak;\n\t\t\t\tcase OP_NEG:\n\t\t\t\t\tret = execute( node.children[0] ) * -1;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tbreak;\n\t\t\t\n\t\tcase NODE_VAR:\n\t\t\tret = Number( getvar( node.value ) );\n\t\t\tbreak;\n\t\t\t\n\t\tcase NODE_CONST:\n\t\t\tret = Number( node.value );\n\t\t\tbreak;\n\t}\n\t\n\treturn ret;\n}\n\n*]\n\n!\t\' |\\r|\\n|\\t\'\n\n\t\"IF\"\n\t\"ELSE\"\n\t\"WHILE\"\n\t\"DO\"\n\t\"SAY\"\n\t\"WRITE\"\n\t\"READ\"\n\t\'{\'\n\t\'}\'\n\t\';\'\n\t\'=\'\n\t\'==\'\n\t\'!=\'\n\t\'<=\'\n\t\'>=\'\n\t\'>\'\n\t\'<\'\n\t\'\\+\'\n\t\'\\-\'\n\t\'/\'\n\t\'\\*\'\n\t\'\\(\'\n\t\'\\)\'\n\t\'#\'\n\t\'[A-Za-z_][A-Za-z0-9_]*\'\tIdentifier\n\t\'\\\'([^\\\']|\\\'\\\')*\\\'\'\t\tString\t\t[* %match = %match.substr( 1, %match.length - 2 );\n\t\t\t\t\t\t\t\t   %match = %match.replace( /\'\'/g, \"\\\'\" );\t*]\n\t\'[0-9]+\'\t\t\tInteger\n\t\'[0-9]+\\.[0-9]*|[0-9]*\\.[0-9]+\'\tFloat\n\t;\n\n##\n\nProgram:\tProgram Stmt\t\t\t[* execute( %2 ); *]\n\t\t|\n\t\t;\n\nStmt_List:\tStmt_List Stmt\t\t\t[* %% = createNode( NODE_OP, OP_NONE, %1, %2 ); *]\n\t\t|\n\t\t;\n\t\t\t\t\t\t\t\t\nStmt:\t\tIF Expression Stmt \t\t[* %% = createNode( NODE_OP, OP_IF, %2, %3 ); *]\n\t\t| IF Expression Stmt ELSE Stmt\t[* %% = createNode( NODE_OP, OP_IF_ELSE, %2, %3, %5 ); *]\n\t\t| WHILE Expression DO Stmt \t[* %% = createNode( NODE_OP, OP_WHILE_DO, %2, %4 ); *]\n\t\t| DO Stmt WHILE Expression \';\'\t[* %% = createNode( NODE_OP, OP_DO_WHILE, %2, %4 ); *]\n\t\t| SAY String \';\'\t\t[* %% = createNode( NODE_OP, OP_SAY, %2 ); *]\n\t\t| WRITE Expression \';\'\t\t[* %% = createNode( NODE_OP, OP_WRITE, %2 ); *]\n\t\t| READ Identifier \';\'\t\t[* %% = createNode( NODE_OP, OP_READ, %2 ); *]\n\t\t| Identifier \'=\' Expression \';\'\t[* %% = createNode( NODE_OP, OP_ASSIGN, %1, %3 ); *]\n\t\t| \'{\' Stmt_List \'}\'\t\t[* %% = %2; *]\n\t\t| \';\'\t\t\t\t[* %% = createNode( NODE_OP, OP_NONE ); *]\n\t\t;\n\t\t\t\t\nExpression:\tExpression \'==\' AddSubExp\t[* %% = createNode( NODE_OP, OP_EQU, %1, %3 ); *]\n\t\t| Expression \'<\' AddSubExp\t[* %% = createNode( NODE_OP, OP_LOT, %1, %3 ); *]\n\t\t| Expression \'>\' AddSubExp\t[* %% = createNode( NODE_OP, OP_GRT, %1, %3 ); *]\n\t\t| Expression \'<=\' AddSubExp\t[* %% = createNode( NODE_OP, OP_LOE, %1, %3 ); *]\n\t\t| Expression \'>=\' AddSubExp\t[* %% = createNode( NODE_OP, OP_GRE, %1, %3 ); *]\n\t\t| Expression \'!=\' AddSubExp\t[* %% = createNode( NODE_OP, OP_NEQ, %1, %3 ); *]\n\t\t| AddSubExp\n\t\t;\n\nAddSubExp:\tAddSubExp \'-\' MulDivExp\t\t[* %% = createNode( NODE_OP, OP_SUB, %1, %3 ); *]\n\t\t| AddSubExp \'+\' MulDivExp\t[* %% = createNode( NODE_OP, OP_ADD, %1, %3 ); *]\n\t\t| MulDivExp\n\t\t;\n\t\t\t\t\nMulDivExp:\tMulDivExp \'*\' NegExp\t\t[* %% = createNode( NODE_OP, OP_MUL, %1, %3 ); *]\n\t\t| MulDivExp \'/\' NegExp\t\t[* %% = createNode( NODE_OP, OP_DIV, %1, %3 ); *]\n\t\t| NegExp\n\t\t;\n\t\t\t\t\nNegExp:\t\t\'-\' Value\t\t\t[* %% = createNode( NODE_OP, OP_NEG, %2 ); *]\n\t\t| Value\n\t\t;\n\nValue:\t\tInteger\t\t\t\t[* %% = createNode( NODE_CONST, %1 ); *]\n\t\t| Float\t\t\t\t[* %% = createNode( NODE_CONST, %1 ); *]\n\t\t| Identifier\t\t\t[* %% = createNode( NODE_VAR, %1 ); *]\n\t\t| \'(\' Expression \')\'\t\t[* %% = %2; *]\n\t\t;\n\n[*\n\nvar str = prompt( \"Please enter an XPL-script to be executed:\",\n\t\"say \\\'Hello World\\\'; i = 0; do { write i; i = i + 1; } while i < 10;\" );\nvar error_cnt \t= 0;\nvar error_off\t= new Array();\nvar error_la\t= new Array();\n\nif( ( error_cnt = __parse( str, error_off, error_la ) ) > 0 )\n{\n\tfor( i = 0; i < error_cnt; i++ )\n\t\talert( \"Parse error near >\" \n\t\t\t+ str.substr( error_off[i], 30 ) + \"<, expecting \\\"\" + error_la[i].join() + \"\\\"\" );\n}\n*]" );

		</script>
	</head>
	<body>
		<table width="100%" border="0" cellpadding="0" cellspacing="2">
			<tr>
				<td colspan="2" id="copyrightinfo">
					<div id="progname">
						<img src="jscc_logo_small.png" title="JS/CC Logo" alt="Logo of the JS/CC project" /><br />
						Web Environment
					</div>
					<div id="version">
						<script type="text/javascript">
						<!--
							document.write( "Version " + JSCC_VERSION );
						-->
						</script>
					</div>
					<div id="copyright">Copyright &copy; 2007, 2008 by Jan Max Meyer, J.M.K S.F. Software Technologies</div>
					<div id="visit_us"><a href="http://jscc.jmksf.com">http://jscc.jmksf.com</a></div>
				</td>
			</tr>
			<tr>
				<td colspan="2" class="elem_title">
					Grammar Editor
				</td>
			</tr>
			<tr>
				<td colspan="2">
					<form action="" name="source">
						<table width="100%" style="margin: 0; padding: 0;" cellpadding="0" cellspacing="0">
							<tr>
								<td width="100%">
								    <select name="stored" size="1" style="width: 100%">
	     								<option value="0">Calculator</option>
	      								<option value="1">Example Programming Language</option>
	    							</select>
								</td>
								<td>
									<input type="button" value="Load" onclick="load_grammar()" />									
								</td>
								<!--
								<td>
									<input type="button" value="Save" />
								</td>
								-->
								<td>
									<input type="button" value="Clear" onclick="check_editor_content()" />
								</td>
							</tr>
						</table>
						
						<textarea id="code" name="code" rows="10" cols="255" style="width: 100%;" onchange="document.source.run.disabled = true;"></textarea>
						<table width="100%">
						<tr>
							<td width="50%">
								<input type="button" value="Build" style="width:100%" onclick="build()" />
							</td>
							<td width="50%">
								<input type="button" name="run" value="Run" style="width:100%" onclick="run_parser()" disabled="disabled" />
							</td>
						</tr>
						</table>

						<input name="with_warnings" type="checkbox" />Show warnings
					</form>
				</td>
			</tr>
			<tr>
				<td class="elem_title">
					Grammar/State Overview &amp; Parse Tables <a href="javascript:enlarge_content( 'output' );"><img src="img/zoom.gif" /></a>
				</td>
				<td class="elem_title">
					Parse Tree <a href="javascript:enlarge_content( 'parsetree' );"><img src="img/zoom.gif" /></a>
				</td>
			</tr>
			<tr>
				<td width="50%">
					<div id="output">
						<!-- Element to output debugging information -->
						Please load or enter a grammar!
					</div>
				</td>
				<td width="50%">
					<div id="parsetree">
						<!-- Element to output generated tables -->
						Run your parser to construct the parse tree!
					</div>
				</td>
			</tr>
			<tr>
				<td colspan="2" class="elem_title">
					Parser Source Code <a href="javascript:enlarge_content( 'js_code' );"><img src="img/zoom.gif" /></a>
				</td>					
			</tr>
			<tr>
				<td colspan="2">
					<div id="js_code">
					Run your parser to obtain the source code!
					</div>
				</td>
			</tr>				
		</table>
		<div id="popupcontent"></div>
	</body>
</html>